S02-02 CSS-布局
[TOC]
盒模型
CSS 就三个大模块: 盒子模型 、 浮动 、 定位。其余的都是细节。要求这三部分,无论如何也要学的非常精通。
网页布局的本质
网页布局中,我们是如何把里面的文字,图片,按照美工给我们的效果图排列的整齐有序呢?
牛奶是怎样运输,让消费者购买的呢?
我们说过,行内元素比如 文字 类似牛奶,也需要一个盒子把他们装起来,我们前面学过的双标签都是一个盒子。有了盒子,我们就可以随意的,自由的,摆放位置了。
网页布局的本质: 把网页元素比如文字图片等等,放入盒子里面,然后利用 CSS 摆放盒子的过程,就是网页布局。
CSS 其实没有太多逻辑可言 , 类似我们小时候玩的积木,我们可以自由的,随意的摆放出我们想要的效果。
盒子模型 Box Model
盒子模型(Box Model):就是把 HTML 页面中的元素看作是一个矩形的盒子,也就是一个盛装内容的容器。每个矩形都由元素的内容、内边距(padding)、边框(border) 和 外边距(margin) 组成。
这里略过 老旧的 ie 盒子模型(IE6 以下),对不起,我都没见过 IE5 的浏览器。
首先,我们来看一张图,来体会下什么是盒子模型。
所有的文档元素(标签)都会生成一个矩形框,我们称为元素框(element box),它描述了一个文档元素在网页布局汇总所占的位置大小。因此,每个盒子除了有自己大小和位置外,还影响着其他盒子的大小和位置。
内容宽高 width/height
基本语法
width/height:是 CSS 中最核心的尺寸属性,用于控制元素内容的宽度和高度。
语法:
selector {
width: <Length>;
height: <Length>;
}
参数:
- Length:
长度值|百分比
,长度单位。
注意:
块级元素适用:width 和 height 仅适用于块级元素,对行内元素无效( img 标签和 input 除外)。
外边距折叠:计算盒子模型的总高度时,还应考虑上下两个盒子垂直外边距折叠的情况。
如果一个盒子没有给定宽度/高度或者继承父亲的宽度/高度,则 padding 不会影响本盒子大小。
相关属性:
- min-width:
<value>
,最小宽度。 - max-width:
<value>
,最大宽度。 - min-height:
<value>
,最小高度。 - max-height:
<value>
,最大高度。
Length@
长度值:
绝对单位:
px
(像素)、pt
(点)、cm
(厘米)、mm
(毫米)、in
(英寸)相对单位:
em
:相对于当前元素的字体大小。rem
:相对于根元素(html)的字体大小。vw
/vh
:视口宽度/高度的1%。vmin
/vmax
:视口较小/较大尺寸的1%。
csswidth: 50vw; /* 视口宽度的一半 */ height: 25rem; /* 25倍根元素字体大小 */
百分比:相对于包含块(containing block)的宽度(width)或高度(height)
csswidth: 50%; /* 父容器宽度的一半 */ height: 100%; /* 父容器高度的100% */
函数值:
min():
()
,取最小值。csswidth: min(100px, 50%, 10vw);
max():
()
,取最大值。csswidth: max(200px, 30%);
clamp():
()
,定义范围。csswidth: clamp(200px, 50%, 1000px); /* 不小于200px,不大于1000px,理想值50% */
盒子边框 border
基本语法
边框(border):就是用于设置各种单独的边界属性的简写属性。
语法:
border: border-width || border-style || border-color;
参数:
- border-width:
Length
,边框宽度。 - border-style:
none|solid|dashed|dotted|double|...
,边框样式。none
:没有边框即忽略所有边框的宽度(默认值)solid
:边框为单实线(最为常用的)dashed
:边框为虚线dotted
:边框为点线double
:边框为双实线
- border-color:
Color
,边框颜色。
示例:基本使用
border: 2px solid red;
边框写法总结
边框写法总结:
- 分方向简写:
- border-top:
width style color
,顶部边框。 - border-right:
width style color
,右侧边框。 - border-bottom:
width style color
,底部边框。 - border-left:
width style color
,左侧边框。 - 分方向单独属性:以
border-top
为例,其他方向类似 - border-top-width:顶部边框宽度。
- border-top-style:顶部边框样式。
- border-top-color:顶部边框颜色。
- 综合单独属性:
- border-width:
上 右 下 左
,边框宽度。 - border-style:
上 右 下 左
,边框样式。 - border-color:
上 右 下 左
,边框样色。 - 综合写法:
- border:
四边宽度 四边样式 四边颜色
,边框综合写法。
示例:
分方向边框简写
css/* 顶部边框 */ border-top: 2px solid red; /* 右侧边框 */ border-right: 1px dashed #333; /* 底部边框 */ border-bottom: 3px double blue; /* 左侧边框 */ border-left: thin dotted green;
分方向单独属性:
css/* 分方向简写 */ border-top: 2px solid red; /* 等价于 */ border-top-width: 2px; border-top-style: solid; border-top-color: red;
综合单独属性:
css/* 简写形式 */ border: 2px solid red; /* 等价于 */ border-width: 2px; border-style: solid; border-color: red;
border-collapse
语法格式:
border-collapse:separate | collapse
,表格边框合并,它决定相邻单元格的边框是合并为单一边框还是分开显示。
- separate:默认,每个单元格有独立的边框,相邻边框分开显示。
- collapse:边框合并模式,相邻单元格共享一个边框,表格呈现更整洁的视觉效果。
示例:最佳实践
/* 推荐全局设置 */
table {
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 0.5em 1em;
border: 1px solid #ddd;
}
border-radius(CSS3)
border-radius:用于设置元素的外边框圆角。
语法格式:
border-radius: 左上角 右上角? 右下角? 左下角?;
示例:
基本语法:设置四个角的半径
css/* 单值:四个角相同 */ border-radius: 10px; /* 双值:左上右下 | 右上左下 */ border-radius: 10px 20px; /* 三值:左上 | 右上左下 | 右下 */ border-radius: 10px 20px 30px; /* 四值:左上 | 右上 | 右下 | 左下 */ border-radius: 10px 20px 30px 40px;
高级语法:设置椭圆角(水平/垂直半径)
css/* 椭圆角:水平半径 / 垂直半径 */ border-radius: 50px / 25px; /* 混合使用 */ border-radius: 10px 20px 30px 40px / 5px 10px 15px 20px;
内边距 padding
padding:属性用于设置内边距。 是指边框与内容之间的距离。
- 分方向属性:
- padding-top:
Length
,上内边距。 - padding-right:
Length
,右内边距。 - padding-bottom:
Length
,下内边距。 - padding-left:
Length
,左内边距。 - 综合写法:
- padding:
上 右? 下? 左?
,内边距。
特性:
百分比计算:百分比值始终基于父元素的宽度(包括垂直方向)。
css.child { padding: 10%; /* 在宽度400px的父元素中 = 40px */ }
负值无效:
padding
不支持负值(与margin
不同)。默认值:所有元素的
padding
默认值为0
。尺寸影响:
标准盒模型:会增加元素总尺寸
css.box { width: 200px; padding: 20px; /* 实际宽度 = 200 + 20 + 20 = 240px */ }
替代盒模型:内边距包含在设定尺寸内
css.box { box-sizing: border-box; width: 200px; padding: 20px; /* 内容宽度 = 200 - 20 - 20 = 160px */ }
示例:
综合写法:设置四个方向的内边距
css/* 单值:四个方向相同 */ padding: 20px; /* 双值:上下 | 左右 */ padding: 10px 20px; /* 三值:上 | 左右 | 下 */ padding: 10px 20px 15px; /* 四值:上 | 右 | 下 | 左(顺时针) */ padding: 10px 15px 20px 25px;
分方向属性
csspadding-top: 10px; padding-right: 15px; padding-bottom: 20px; padding-left: 25px;
新浪导航
外边距 margin
基本语法
margin:属性用于设置外边距。 设置外边距会在元素之间创建“空白”, 这段空白通常不能放置其他内容。
- 分方向属性:
- margin-top:
Length
,上外边距。 - margin-right:
Length
,右外边距。 - margin-bottom:
Length
,下外边距。 - margin-left:
Length
,左外边距。 - 综合写法:
- margin:
上 右? 下? 左?
,外边距。
margin应用
水平居中
条件:可以让一个盒子实现水平居中,需要满足一下两个条件:
- 必须是块级元素。
- 盒子必须指定了宽度(width)
实现思路:然后就给左右的外边距都设置为 auto,就可使块级元素水平居中。
实际工作中常用这种方式进行网页布局,示例代码如下:
.header {
width: 960px;
margin: 0 auto;
}
文字居中 VS 盒子居中
文字水平居中:text-align: center
text-align: center; /* 文字居中水平 */
盒子水平居中:margin: 0 auto
margin: 10px auto; /* 盒子水平居中 左右margin 改为 auto 就阔以了 */
插入图片 VS 背景图片
插入图片:我们用的最多,比如产品展示类。
section img {
width: 200px; /* 插入图片更改大小 width 和 height */
height: 210px;
margin-top: 30px; /* 插入图片更改位置 可以用margin 或padding 盒模型 */
margin-left: 50px; /* 插入当图片也是一个盒子 */
}
背景图片:我们一般用于小图标背景或者超大背景图片。
aside {
width: 400px;
height: 400px;
border: 1px solid purple;
background: #fff url(images/sun.jpg) no-repeat;
background-size: 200px 210px; /* 背景图片更改大小只能用 background-size */
background-position: 30px 50px; /* 背景图片更该位置 我用 background-position */
}
重置默认边距
重置默认边距:为了更方便地控制网页中的元素,制作网页时,可使用如下代码清除元素的默认内外边距:
* {
padding: 0; /* 清除内边距 */
margin: 0; /* 清除外边距 */
}
行内元素处理
行内元素处理:
- 问题:
- 外边距:行内元素只有左右外边距的,没有上下外边距。
- 内边距:在 ie6 等低版本浏览器也会有问题。
- 解决:我们尽量不要给行内元素指定上下的内外边距就好了。
BFC@
概念
FC(Formatting Context,格式化上下文):是 CSS 渲染页面时的核心布局概念,它定义了元素如何排列、定位及相互作用的规则。不同类型的 FC 对应不同的布局模式,开发者可通过 CSS 属性触发特定的 FC,以实现不同的布局效果。它分为:BFC、IFC、FFC、GFC。
BFC(Block Formatting Context,块级格式化上下文):是 CSS 渲染页面时用于控制块级盒子布局的一个独立区域。BFC 内的元素布局不受外部影响,同时内部的布局规则也不会影响外部元素。
IFC(Inline Formatting Context,行内格式化上下文):是 CSS 中用于控制行内级元素(如文本、图片、行内块元素)布局的规则。它定义了行内元素如何在水平方向排列、垂直对齐以及如何处理空白符等行为。
分类:
- BFC: 块级格式化上下文(Block Formatting Context)。块级元素的布局属于 BFC
- IFC:行内级格式化上下文(Inline Formatting Context)。行内级元素的布局属于 IFC
BFC触发条件
满足以下任一条件即可创建 BFC:
触发条件 | 示例 | 说明 |
---|---|---|
根元素 | <html> | 页面根元素自动创建 BFC |
浮动元素 | float: left/right; | 不为 none 的浮动元素 |
绝对定位 | position: absolute/fixed; | 绝对或固定定位元素 |
行内块元素 | display: inline-block; | 行内块级元素 |
表格元素 | display: table-cell/table-caption; | 表格单元格或标题 |
弹性布局 | display: flex/inline-flex; | Flex 容器 |
网格布局 | display: grid/inline-grid; | Grid 容器 |
overflow 不为 visible | overflow: hidden/auto/scroll; | 最常用的触发方式 |
contain 属性 | contain: layout/content/paint; | CSS 新特性 |
多列容器 | column-count/column-width: 非auto值; | 多列布局容器 |
display: flow-root | display: flow-root; | 专门创建 BFC 的属性(推荐) |
BFC布局规则
- 内部元素垂直排列:在 BFC 中,box 会在垂直方向上一个挨着一个的排布。
- 垂直方向的间距由 margin 属性决定。
- 外边距折叠规则:在同一个 BFC 中,相邻两个 box 之间的 margin 会折叠(collapse)。
- 在 BFC 中,每个元素的左边缘是紧挨着包含块的左边缘的。
- 浮动元素参与高度计算:BFC 会计算其内部所有浮动元素的高度。
- BFC区域不会与浮动元素重叠
BFC应用
解决margin折叠(权威)
依据:在同一个 BFC 中,相邻两个 box 之间的 margin 会折叠(collapse)

解决思路:让两个 box 属于不同的 BFC,就可以解决折叠问题
示例:

解决float高度塌陷(权威)
BFC 解决高度塌陷需要满足两个条件:
- 浮动元素的父元素触发 BFC,形成独立的块级格式化上下文(Block Formatting Context)
- 浮动元素的父元素的高度是 auto的
原理: BFC 的高度是 auto 的情况下,是如下方法计算高度的:
- 如果只有 inline-level,是行高的顶部和底部的距离
- 如果有 block-level,是由最底层的块上边缘和最底层 块盒子的下边缘之间的距离
- 如果有绝对定位元素,将被忽略
- 如果有浮动元素,那么会增加高度以包裹这些浮动元素的下边缘
示例:


防止文字环绕
问题:文字默认会环绕浮动元素
解决思路:为文字元素创建BFC
示例:
最佳实践
开始学习盒子模型,同学们最大的困惑就是, 分不清内外边距的使用,什么情况下使用内边距,什么情况下使用外边距?
最佳实践:
- 大部分情况下可以混用。
- 推荐根据稳定性的优先级来选择:
width/height
>padding
>margin
。- margin:有以下2个问题,所以最后使用。
- 有外边距折叠问题
- IE6 下 margin 加倍的 BUG(讨厌)。
- padding:会影响盒子大小, 需要进行加减计算(麻烦), 其次使用。
- width:没有问题(嗨皮),我们经常使用宽度剩余法 高度剩余法来做。
- margin:有以下2个问题,所以最后使用。
box-sizing(CSS3)
box-sizing:content-box|border-box
,CSS 中控制盒子模型计算方式的核心属性,它决定了元素的宽度(width)和高度(height)如何计算内边距(padding)和边框(border)。
content-box
:默认,标准盒模型,width/height = 内容
。border-box
:推荐,替代盒模型,width/height = 内容 + padding + border
。
示例:
两种盒模型对比
css/* 标准盒模型 (content-box) */ .element { box-sizing: content-box; width: 200px; padding: 20px; border: 5px solid; /* 总宽度 = 200 + 40 + 10 = 250px */ } /* 替代盒模型 (border-box) */ .element { box-sizing: border-box; width: 200px; padding: 20px; border: 5px solid; /* 内容宽度 = 200 - 40 - 10 = 150px */ }
推荐 border-box 的理由:
- 简化百分比计算。
- 避免意外的布局溢出。
- 使内边距和边框不影响整体布局。
- 提高代码可维护性。
最佳实践:
/* 全局设置 */
:root {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit; /* 更好的实践 */
}
/* 特定元素恢复 */
.content-box-element {
box-sizing: content-box;
}
box-shadow(CSS3)
box-shadow:inset? offset-x offset-y blur-radius? spread-radius? color?
,用于为元素添加阴影效果的属性,它可以创建从简单投影到复杂立体效果的多种视觉效果。
- inset?:
省略|inset
,默认:外阴影
,阴影类型(内阴影/外阴影)。省略
:默认,外阴影。inset
:内阴影。
- offset-x:
Length
,默认:0
,水平偏移(正值向右)。 - offset-y:
Length
,默认:0
,垂直偏移(正值向下)。 - blur-radius?:
Length
,默认:0
,取值范围:>=0
,模糊半径(值越大越模糊)。 - spread-radius?:
Length
,默认:0
,扩散半径(正数扩大,负数缩小)。 - color?:
Color
,默认:currentColor
, 阴影颜色。
性能优化:
- 模糊半径:值越大性能开销越大
- 阴影数量:多个阴影增加渲染负担
- 动画阴影:持续变化的阴影性能开销大
示例:
基本使用
css.box { box-shadow: 5px 5px 10px rgba(0,0,0,0.5); }
内阴影
css.box { box-shadow: inset 0 0 20px rgba(0,0,0,0.8); }
多重阴影
css.box { box-shadow: 0 0 10px #fff, 0 0 20px #f0f, 0 0 30px #0ff; }
布局
display
网页的标签非常多,不同地方会用到不同类型的标签,以便更好的完成我们的网页。
标签类型分类:HTML 标签按显示模式一般分为块标签和行内标签两种类型,它们也称块元素和行内元素。
块级元素 block-level
块级元素(Block-Level Elements):默认情况下会在新行开始显示,并尽可能占据其父容器的全部可用宽度。
语法:
display: block;
核心特性:
- 独占一行:默认从新行开始,前后都有换行,
div
后总是换行。 - 宽度扩展:自动填满父容器可用宽度,即使内容很少也占满宽度。
- 尺寸可控:可设置 width/height,可设置固定尺寸。
- 盒模型完整:支持所有盒模型属性,margin, padding, border 等。
- 可包含其他元素:通常可包含其他块级和内联元素,
div
包含p
,span
等,(p
、<h1>~<h6>
、dt
只能包含行内元素)。 - 垂直堆叠:默认垂直排列,多个
div
垂直堆叠。
常见块级元素:<div>
、<h1>~<h6>
、<p>
、<ul>
、<ol>
、<li>
。
行内元素 inline-level
行内元素(Inline-Level Elements):默认在文本流中水平排列,不会强制换行,其尺寸由内容决定而非容器宽度。
语法:
display: inline;
核心特性:
- 水平排列:与其他行内元素同行显示,多个
<span>
在同一行。 - 尺寸由内容决定:宽度/高度由内容自动计算,文本长度决定元素宽度。
- 部分盒模型支持:支持水平方向盒模型属性,水平margin/padding有效。
- 不可设置宽高:width/height属性无效,设置width/height不生效。
- 垂直对齐控制:通过vertical-align调整,文字基线对齐调整。
- 内容级语义:通常用于标记文本片段,强调、链接、代码片段。
- 包含关系:行内元素只能容纳文本或其他行内元素。(a 特殊)。
常见行内元素:<span>
、<a>
、<strong>
、<b>
、<em>
、<i>
、<del>
、<s>
、<ins>
、<u>
。
示例:
盒模型控制
css.text-link { /* 水平方向有效 */ padding: 0 10px; margin-right: 15px; /* 垂直方向部分支持 */ line-height: 1.5; /* 控制行高 */ /* 无效设置 */ width: 200px; /* 忽略 */ height: 50px; /* 忽略 */ margin-top: 20px; /* 忽略 */ }
常见问题:
垂直margin无效
问题:行内元素垂直margin无效。
html<span class="top">文本1</span> <span class="bottom">文本2</span>
css.top { margin-bottom: 20px; /* 无效 */ }
解决方案:转为行内块。
css.top { display: inline-block; /* 转为行内块 */ margin-bottom: 20px; /* 有效 */ }
img下方有额外空白
问题:img下方有额外空白。
html<div> <img src="image.jpg"> </div> <!-- div下方有空白 -->
解决方案:
方案一:
vertical-align: 非baseline
cssimg { vertical-align: middle; /* 或 bottom/top */ }
方案二:
display: block
cssimg { display: block; /* 转为块级 */ }
对齐问题
问题:图标与文本不对齐。
html<button> <img src="icon.png"> 保存 </button>
解决方案:
cssimg { vertical-align: middle; }
行内块元素 inline-block
行内块元素(Inline-Block Elements):外观表现为行内元素(水平排列),但行为类似块级元素(可设置宽高、边距等)。
语法:
display: inline-block;
核心特性:
- 水平排列:与其他行内/行内块元素同行显示,类似行内元素。
- 尺寸可控:可设置width/height属性,类似块级元素。
- 完整盒模型:支持所有margin/padding/border,四个方向都有效。
- 垂直对齐控制:默认基线对齐,可调整,通过vertical-align控制。
- 不独占一行:不会强制换行,与相邻元素同行显示。
- 空白符敏感:HTML中的空白会影响布局,元素间可能有间隙。
常见行内块元素:<img>
、<input>
、<textarea>
、<select>
、<button>
。
示例:
最佳实践
css.inline-block-item { display: inline-block; vertical-align: top; /* 始终指定 */ box-sizing: border-box; /* 包含padding/border */ width: calc(33.333% - 20px); /* 响应式宽度 */ margin: 10px; font-size: 16px; /* 重置字体 */ } .inline-block-container { font-size: 0; /* 消除间隙 */ }
常见问题:
空白间隙问题
问题原因:HTML中的换行和空格被解析为文本节点
html<div class="item">项目1</div> <!-- 这里有空白 --> <div class="item">项目2</div>
解决方案:
方案一:父元素
font-size:0
(推荐)css.container { font-size: 0; /* 消除间隙 */ } .item { font-size: 16px; /* 重置字体 */ }
方案二:HTML注释消除空白
html<div class="item">项目1</div><!-- --><div class="item">项目2</div>
方案三:负边距
css.item { margin-right: -4px; }
方案四:浮动替代(改变显示特性)
css.item { float: left; }
垂直不对齐问题
问题:默认基线对齐可能导致布局错位。
html<div class="align-container"> <div class="box" style="height: 80px;">A</div> <div class="box" style="height: 120px;">B</div> <span class="text">文本内容</span> </div>
css.box { display: inline-block; /* 默认基线对齐 */ }
解决方案:垂直对齐设为:
vertical-align: 非 baseline
。css.box { display: inline-block; vertical-align: top; /* 推荐top/middle/bottom */ }
块级VS行内VS行内块
特性 | 块级元素 | 行内元素 | 行内块元素 |
---|---|---|---|
换行 | 换行 | 不换行 | 不换行 |
尺寸 | 可设置 | 内容决定 | 可设置 |
盒模型 | 完整支持 | 水平方向完整 | 完整支持 |
包含关系 | 可含块级/行内 | 仅含文本/行内 | 可含块级/行内 |
垂直对齐 | 无效 | vertical-align有效 | vertical-align有效 |
典型元素 | div, p | span, a | img, input |
布局作用 | 结构布局 | 文本级样式 | 精确控制 |
浮动布局 float
标准流
标准流(Normal Flow,文档流,常规流):描述了元素在没有任何特殊布局干预情况下的默认排列方式。由以下因素决定:
- 元素在 HTML 中的书写顺序
- 元素的显示类型(块级、行内、行内块)
- 元素的盒模型属性
核心特性:
- 自上而下流动:元素按照 HTML 顺序垂直排列。
- 块级元素独占一行:每个块级元素从新行开始。
- 行内元素水平排列:行内元素在同一行从左到右排列。
- 尺寸自适应:宽度默认填满父容器(块级),高度由内容决定。
- 盒模型应用:margin、padding、border 正常生效。
- 非定位模式:不脱离文档流(position: static/relative)。
脱离标准流的方式:
- 浮动
- 绝对定位
- 固定定位
浮动
浮动(float):是 CSS 中一种定位属性,它使元素脱离标准流,并向左或向右移动,直到其外边缘碰到包含块或另一个浮动元素的边缘。
历史:
浮动最早是用来控制图片,以便达到其他元素(特别是文字)实现 “环绕”图片的效果。
后来,我们发现浮动有个很有意思的事情:就是让任何盒子可以一行排列,因此我们就慢慢的偏离主题,用浮动的特性来布局了。
语法:
float:left|right|none|inherit
,用于创建浮动效果的属性,它使元素脱离标准文档流,并向左或向右移动,允许其他内容(特别是文本和内联元素)环绕其周围。
- left:元素向左移动,内容环绕其右侧。
- right:元素向右移动,内容环绕其左侧。
- none:默认,不浮动,元素保持在标准流中。
- inherit:继承父元素的浮动属性。
核心特性:
- 脱离文档流:元素不再占据标准流中的空间,创建多列布局。
- 文字环绕:文本和内联元素环绕浮动元素,图文混排。
- 块级化:浮动元素自动成为块级元素,可设置宽高。
- 方向控制:可向左或向右浮动,布局控制。
- 堆叠顺序:浮动元素位于标准流上方,但低于定位元素,层级控制。
浮动表现
浮动脱离标准流,不占位置,会影响标准流。浮动只有左/右浮动。
包含块:浮动首先创建包含块的概念(包裹)。就是说, 浮动的元素总是找离它最近的父级元素对齐。但是不会超出内边距的范围。
多元素浮动:
- 浮动的元素排列位置,跟上一个元素(块级)有关系。如果上一个元素有浮动,则A元素顶部会和上一个元素的顶部对齐;如果上一个元素是标准流,则A元素的顶部会和上一个元素的底部对齐。
- 父盒子里面的子盒子,如果其中一个子级有浮动的,则其他子级都需要浮动。这样才能一行对齐显示。
清除浮动
浮动元素的问题
浮动元素的问题:当元素设置浮动后,会脱离标准文档流,导致以下问题:
- 高度塌陷:父容器无法包含浮动子元素,高度变为0。
- 布局错乱:后续元素会环绕浮动元素,而非正常排列。
- 背景/边框消失:父容器的背景和边框无法显示。
清除浮动主要为了解决上述因为浮动造成的副作用。
清除方法
清除方法的核心方法是利用CSS中的clear属性:
clear:left|right|both|none
,用于控制元素是否允许浮动元素出现在其旁边。
- left:元素向下移动以清除左浮动元素。
- right:元素向下移动以清除右浮动元素。
- both:元素向下移动以清除所有浮动(左和右)。
- none:默认,元素不会向下移动以清除浮动。
空元素清除法
思路:W3C推荐,在浮动元素末尾添加一个空元素,设置它的样式为 clear:both
。
<div style="clear:both"></div>
优点:通俗易懂,书写方便。
缺点:多出了无意义的标签,结构化较差。
触发BFC
思路:可以通过触发 BFC 的方式,可以实现清除浮动效果。
触发BFC的传统方法:为父元素添加
overflow: hidden|auto|scroll
。html<div class='parent' style="overflow: hidden"> <div class="float">浮动元素</div> <div class="float">浮动元素</div> </div>
触发BFC的现代方法:为父元素添加
display: flow-root
。css<div class='parent' style="display: flow-root"> <div class="float">浮动元素</div> <div class="float">浮动元素</div> </div>
优点:代码简洁。
缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。
伪元素清除法@
思路:::after
是空元素的升级版,好处是不用添加额外标签。
::after
:创建伪元素作为父容器的最后一个子元素。display: block
:创建块级格式化上下文。clear: both
:清除两侧浮动
.clearfix::after {
content: "";
display: table;
clear: both;
}
<div class="parent clearfix">
<div class="float-child">浮动元素</div>
</div>
优点:符合闭合浮动思想,结构语义化正确。
定位布局 position
如果,说浮动, 关键在一个 “浮” 字上面, 那么 我们的定位,关键在于一个 “位” 上。
PS: 定位是我们 CSS 算是数一数二难点的了,但是,你务必要学好它,我们 CSS 离不开定位,特别是后面的 js 特效,天天和定位打交道。不要抵触它,反而要爱上它,它可以让我们工作更加轻松哦!
应用场景
那么定位,最常运用的场景再那里呢? 来看几幅图片,你一定会有感悟!
第一幅图,小黄色块可以在图片上移动:
第二幅图, 左右箭头压住图片:
第三幅图, hot 在盒子外面多出一块,更加突出:
以上三个小地方,如果用标准流或者浮动,实现会比较复杂或者难以实现,此时我们用定位来做,just soso!
基本语法
定位组成:元素的定位属性主要包括定位模式和边偏移两部分,定位需要和边偏移搭配使用。
边偏移:
- top:
Length
,顶端偏移量,定义元素相对于其父元素上边线的距离。 - bottom:
Length
,底部偏移量,定义元素相对于其父元素下边线的距离。 - left:
Length
,左侧偏移量,定义元素相对于其父元素左边线的距离。 - right:
Length
,右侧偏移量,定义元素相对于其父元素右边线的距离。
定位模式(定位的分类):
- position:
static|relative|absolute|fixed|sticky
,决定了元素在文档中的定位方式。- static:默认,元素遵循标准文档流。
- relative:相对定位,相对于其原文档流的位置进行定位。
- absolute:绝对定位,相对于其上一个已经定位的父元素进行定位。
- fixed:固定定位,相对于浏览器窗口进行定位。
- sticky:粘性定位,在特定阈值内相对定位,超过阈值后固定定位
静态定位 static
静态定位(static):是元素的默认定位方式,元素遵循标准文档流的规则:
- 元素按照 HTML 中的顺序渲染。
- 块级元素垂直堆叠(从上到下)。
- 行内元素水平排列(从左到右)。
- 不响应
top
,right
,bottom
,left
和z-index
属性。
语法:
position: static; /* 默认值,通常省略 */
应用场景:
重置定位状态
css/* 移除其他定位效果 */ .reset-position { position: static; top: auto; right: auto; bottom: auto; left: auto; z-index: auto; }
性能优化:动画结束恢复静态
css/* 动画元素结束状态 */ .animated-element { position: absolute; animation: move 2s forwards; } @keyframes move { to { position: static; /* 动画结束恢复静态 */ } }
相对定位 relative
相对定位(relative):是元素相对于自身在文档流中的原始位置进行偏移的一种定位方式:
- 元素保留原始空间(其他元素不会填补其位置)
- 通过
top
,right
,bottom
,left
属性进行位置调整 - 创建新的定位上下文(子元素可基于其进行绝对定位)
语法:
position: relative;
核心特性:
标准流保留:元素仍占据原始空间,其他元素布局不受影响。
偏移控制:可设置四个方向的偏移值,元素视觉位置改变。
- 对立属性:同时设置
top/bottom
或left/right
时,top/left
优先。 - 负值:允许反向偏移(如
top: -10px
向上移动)。 - 百分比:基于元素自身尺寸计算(非父容器)。
- 对立属性:同时设置
层叠控制:支持
z-index
属性,可调整元素堆叠顺序。定位上下文:成为子元素的定位参考,子元素可基于其绝对定位。
应用场景:
微调元素位置
css.icon { position: relative; top: -3px; /* 垂直微调图标位置 */ } .heading { position: relative; left: 10px; /* 水平微调标题位置 */ }
创建定位上下文
css.container { position: relative; /* 创建定位上下文 */ } .child { position: absolute; top: 10px; left: 20px; /* 相对于.container定位 */ }
视觉层次提升
css.card { position: relative; z-index: 1; /* 提升堆叠顺序 */ } .card:hover { z-index: 2; /* 悬停时更高层级 */ }
伪元素定位
css.button { position: relative; } .button::after { content: ""; position: absolute; top: 0; right: 0; width: 10px; height: 10px; background: red; border-radius: 50%; }
动画与过渡起点
css.animated-element { position: relative; left: 0; transition: left 0.3s ease; } .animated-element:hover { left: 20px; /* 平滑过渡效果 */ }
绝对定位 absolute
绝对定位(absolute):允许你将元素精确地放置在页面上的任意位置,完全脱离正常的文档流。
语法:
position: absolute;
核心特性:
脱离文档流:
- 绝对定位的元素不占用原始空间,后续元素会忽略它的存在(会“填补”它原本的位置)。
- 例如:一个设置了
absolute
的<div>
会“漂浮”在页面上,不影响其他元素的布局。
定位基准点(子绝父相):
相对于最近的非
static
定位的祖先元素定位(即祖先元素需设置position: relative/absolute/fixed/sticky
)。如果找不到符合条件的祖先,则相对于整个浏览器视口(viewport) 定位。
位置控制: 通过
top
,right
,bottom
,left
属性精确控制偏移量:css.box { position: absolute; top: 50px; /* 距离参照物顶部 50px */ left: 100px; /* 距离参照物左侧 100px */ }
层叠控制:使用
z-index
控制绝对定位元素的层级(仅在定位元素间有效)。尺寸自适应:绝对定位的元素默认宽度由内容撑开,可通过
width: 100%
或left/right
组合拉伸:css.full-width { position: absolute; /* 宽度铺满参照物 */ left: 0; right: 0; }
跟随滚动:如果文档可滚动,绝对定位元素会随着它滚动,因为元素最终会相对于标准流的某一部分定位。
应用场景:
水平垂直居中:
思路:
left/top:50%
:父盒子的一半大小。margin-left/top: -1/2 * width、height
:自己宽高的负一半值。
css.parent { position: relative; } .box { width: 100px; height: 100px; /* 绝对定位 */ position: absolute; /* 父盒子的一半大小 */ left: 50%; top: 50%; /* 自己宽高的负一半值 */ margin-left: -50px; margin-top: -50px; }
固定定位 fixed
固定定位(fixed):让元素相对于浏览器视口(viewport)定位,并且滚动页面时保持固定不动。
语法:
position: fixed;
核心特性:
相对于视口定位:
- 无论页面如何滚动,元素始终固定在屏幕的指定位置
- 定位基准永远是浏览器窗口(而非父元素)
css.fixed-element { position: fixed; top: 20px; /* 距离视口顶部 20px */ right: 50px; /* 距离视口右侧 50px */ }
完全脱离文档流:
- 不占用页面空间(后续元素会填补其位置)
- 不影响其他元素的布局
滚动免疫:
- 页面滚动时元素保持固定,像"粘"在屏幕上
- 典型应用:导航栏、返回顶部按钮、客服悬浮窗
注意事项:
层级控制:使用
z-index
控制固定元素的叠放顺序(避免被其他内容覆盖)移动端特殊行为:在 iOS Safari 等移动浏览器中,滚动时可能临时禁用 fixed 定位(需用 JS 或
position: sticky
替代方案)祖先元素的影响:若祖先元素设置了以下属性,fixed 定位可能失效:
csstransform: translate(10px, 10px); /* 或 filter, perspective 等 */
尺寸控制:固定定位元素默认宽度由内容决定,常用组合:
css/* 全屏覆盖 */ .overlay { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.5); }
应用场景:
固定导航栏:灰色导航栏始终固定在页面顶部,滚动页面时不会移动。
html<header class="fixed-header">我是固定导航栏</header> <div class="content">(长内容...)</div>
css.fixed-header { position: fixed; top: 0; /* 紧贴视口顶部 */ left: 0; /* 紧贴视口左侧 */ width: 100%; /* 铺满视口宽度 */ background: #333; color: white; padding: 15px; z-index: 1000; /* 确保显示在最顶层 */ } .content { margin-top: 60px; /* 预留导航栏空间,防止内容被遮挡 */ }
侧边悬浮工具
css.chat-widget { position: fixed; bottom: 30px; right: 30px; }
粘性定位 sticky
粘性定位(sticky):结合了相对定位和固定定位的特性。当元素在视口中时表现为相对定位,而当元素滚动到特定位置时会变为固定定位。
语法:
position: sticky;
核心特性:
- 混合定位模式:
- 在特定阈值(由
top
,right
,bottom
,left
定义)之前表现为position: relative
- 滚动超过阈值后变为
position: fixed
- 在特定阈值(由
- 定位基准点:
- 相对于最近的滚动祖先(具有滚动机制的容器)定位
- 如果无滚动祖先,则相对于视口定位
- 不脱离文档流:
- 粘性元素保留在正常文档流中
- 不会影响其他元素的布局(这点与 fixed/absolute 不同)
示例:
基本使用
css.sticky-element { position: sticky; top: 20px; /* 触发固定定位的阈值 */ }
定位方式对比
特性 | 静态定位 (static) | 相对定位 (relative) | 绝对定位 (absolute) | 固定定位 (fixed) |
---|---|---|---|---|
文档流 | 在流中 | 在流中(保留空间) | 脱离流 | 脱离流 |
偏移属性 | 无效 | 有效 | 有效 | 有效 |
定位参考 | 无 | 自身原始位置 | 最近定位祖先 | 视口 |
z-index | 无效 | 有效 | 有效 | 有效 |
创建定位上下文 | 否 | 是 | 是 | 是 |
常见用途 | 默认布局 | 微调位置 | 精确控制位置 | 固定位置元素 |
z-index
z-index:auto | <integer> | unset
,用于控制元素在 z 轴(垂直于屏幕方向)上的堆叠顺序的属性。
auto :默认,相当于
z-index: 0
的效果,但不会创建新层叠上下文。<integer>:
number
,取值范围:正负整数(包括0)
,- 值越大:元素在层叠顺序中越靠前(更靠近用户)。
- 值越小:元素越靠后。
- 值相同:元素按它们在HTML中出现的顺序堆叠(后来居上)。
unset:重置为自然值(可能是
auto
或inherit
)。
示例:
基础堆叠:box2覆盖在box1上方
html<div class="box box1">Box 1 (z-index: 1)</div> <div class="box box2">Box 2 (z-index: 2)</div>
常见问题:
z-index 无效
原因及解决:
- 元素未设置定位 → 添加
position: relative/absolute/fixed
- 被父级层叠上下文限制 → 调整父元素
z-index
或修改父元素创建层叠上下文的属性 - 父元素
z-index: auto
→ 改为整数创建新上下文
- 元素未设置定位 → 添加
层叠上下文创建条件:
- 文档根元素 (
<html>
) position
值为absolute
/relative
且z-index
值不为auto
position
值为fixed
或sticky
opacity
值小于 1transform
值不为none
- 其他属性如
filter
、perspective
、flex
容器的子项等
弹性布局 flex(CSS3)
概念
Flex 布局(Flexible Box Layout):是 CSS3 中一种强大的一维布局模型,专门设计用于创建灵活、响应式的页面布局。它通过简单的属性设置,就能高效地控制容器内项目的排列、对齐、分布和尺寸调整。
核心概念:
- Flex 容器 (Flex Container):通过
display: flex;
或display: inline-flex;
声明,内部所有直接子元素自动成为 Flex 项目。 - Flex 项目 (Flex Items):容器内的直接子元素,可以独立设置灵活的特性。
- 主轴 (Main Axis):项目排列的主要方向(默认水平)。
- 交叉轴 (Cross Axis):垂直于主轴的方向(默认垂直)。
解决的痛点:
- 垂直居中
- 等分宽高
- 多列不等高想占等高的位置
Flex 布局的模型:
概念:
- main start / main end: 主轴开始 / 结束
- cross start / cross end: 交叉轴开始 / 结束
- main size/ cross size: 主轴 / 交叉轴尺寸
- flex container: flex 容器
- flex item: flex 元素
Item 尺寸计算流程:
- 确定
flex-basis
值 - 计算容器可用空间
- 根据剩余空间和
flex-grow
分配额外空间 - 根据超出空间和
flex-shrink
收缩项目 - 应用
min-width
/max-width
约束
item 最终 size 的决定因素:优先级:从高到低
- 1、max-width / max-height / min-width / min-height
- 2、flex-basis
- 3、width / height
- 4、内容本身的 size
API
索引
- 容器 container:
- display:
flex|inline-flex
,用于创建弹性布局模型的核心属性。它会启用一组专用的弹性布局属性。 - justify-content:
flex-start|flex-end|center|space-between|space-around|space-evenly
,默认:flex-start
,用于控制弹性项目在主轴(main axis)上对齐方式。 - align-items:
flex-start|flex-end|center|baseline|stretch
,默认:stretch
,用于控制项目在交叉轴上对齐方式。 - flex-direction:
row|row-reverse|column|column-reverse
,默认:row
,定义主轴方向,决定了 flex 容器内项目的排列方向和顺序。 - flex-wrap:
wrap|nowrap|wrap-reverse
,默认:nowrap
,控制项目是否换行以及换行方向。 - flex-flow:
<flex-direction> || <flex-wrap>
,用于 同时设置flex-direction
和flex-wrap
的简写属性。 - align-content:
flex-start|flex-end|center|space-between|space-around|space-evenly|stretch
,默认:stretch
,控制多行内容在交叉轴上的对齐方式,决定了容器内多行(或轨道)之间的空间分布方式。 - 子元素 items:
- flex-grow:
number
,默认:0
,控制项目如何分配容器剩余空间的关键属性,它决定了项目如何沿主轴方向扩展。 - flex-shrink:
number
,默认:1
,控制项目在空间不足时如何收缩的关键属性。 - flex-basis:
auto|<width>|content
,默认:auto
,定义项目在主轴方向上的初始尺寸。 - flex:
none|auto|<flex-grow>|<flex-shrink>|<flex-basis>
,用于 同时设置flex-grow
、flex-shrink
和flex-basis
的简写属性。 - order:
number
,默认:0
,控制弹性项目或网格项目在容器内的显示顺序。 - align-self:
flex-start|flex-end|center|baseline|stretch|auto
,控制单个项目在交叉轴上的对齐方式,允许覆盖容器上设置的align-items
值。
容器属性
display
display:flex|inline-flex
,用于创建弹性布局模型的核心属性。它会启用一组专用的弹性布局属性。
flex
:创建块级弹性容器。inline-flex
:创建行内弹性容器。
示例:
弹性容器创建:
css/* 块级弹性容器 */ .flex-container { display: flex; /* 占据整行 */ } /* 行内弹性容器 */ .inline-flex-container { display: inline-flex; /* 仅占据内容宽度 */ }
justify-content
justify-content:flex-start|flex-end|center|space-between|space-around|space-evenly
,默认:flex-start
,用于控制弹性项目在主轴(main axis)上对齐方式。
flex-start
:默认,项目向主轴起点对齐。flex-end
:项目向主轴终点对齐。center
:项目在主轴居中。space-between
:首尾项目贴边,中间项目等距。space-around
:每个项目两侧有相等空间。space-evenly
:所有空间均匀分配(包括边缘)。
语法特性:
主轴方向决定行为:
justify-content
的行为取决于主轴方向:flex-direction: row
:控制水平分布。flex-direction: column
:控制垂直分布。
应用场景:
水平垂直居中
css.center-container { display: flex; justify-content: center; /* 主轴居中 */ align-items: center; /* 交叉轴居中 */ min-height: 100vh; }
常见问题:
最后一行不对齐问题
问题: Flex 布局中设置
justify-content
后最后一行不对齐,如图:解决: 在 items 最后加上最少
列数 - 2
个 span,span 设置如下
align-items
align-items: flex-start|flex-end|center|baseline|stretch
,默认:stretch
,用于控制项目在交叉轴上对齐方式。
flex-start
:项目向交叉轴起点对齐。flex-end
:项目向交叉轴终点对齐。center
:项目在交叉轴居中。baseline
:项目按基线对齐。stretch
:默认,项目拉伸填满容器高度。
语法特性:
交叉轴方向:
align-items
的行为取决于交叉轴方向:- 在 Flexbox 中,交叉轴垂直于主轴。
- 在 Grid 中,交叉轴通常是垂直方向(块轴)。
与 align-self 的关系:
align-items
:设置容器内所有项目的默认对齐方式。align-self
:可覆盖单个项目的对齐方式。
应用场景:
水平垂直居中:
css.center-container { display: flex; justify-content: center; /* 主轴居中 */ align-items: center; /* 交叉轴居中 */ min-height: 100vh; }
常见问题:
等高列问题:
css.card-container { display: flex; align-items: stretch; /* 确保所有卡片等高 */ } .card { width: 250px; /* 不需要设置高度 */ }
混合内容对齐:
css.icon-text { display: flex; align-items: center; /* 图标和文本垂直居中 */ gap: 8px; }
基线对齐问题:
css.baseline-container { display: flex; align-items: baseline; } /* 确保所有项目有文字内容 */ .item::before { content: ""; display: inline-block; height: 1em; /* 创建基线参考 */ }
flex-direction
flex-direction: row|row-reverse|column|column-reverse
,默认:row
,定义主轴方向,决定了 flex 容器内项目的排列方向和顺序。
row
:默认,主轴项目从左向右排列。row-reverse
:主轴项目从右向左排列。column
:主轴项目从上向下排列。column-reverse
:主轴项目从下向上排列。
语法特性:
- 主轴与交叉轴:
row
/row-reverse
:主轴水平,交叉轴垂直column
/column-reverse
:主轴垂直,交叉轴水平
- 方向与书写模式:
flex-direction
的值受文档书写模式影响:- 在 RTL(从右向左)语言中:
row
:从右向左row-reverse
:从左向右
- 在 RTL(从右向左)语言中:
示例:
基础导航栏:
html<nav class="navbar"> <a href="#">首页</a> <a href="#">产品</a> <a href="#">服务</a> <a href="#">关于</a> </nav>
css.mobile-menu { display: flex; flex-direction: column; width: 250px; background: #f0f0f0; box-shadow: 2px 0 10px rgba(0,0,0,0.1); } .menu-item { padding: 15px; border-bottom: 1px solid #ddd; }
flex-wrap
flex-wrap: wrap|nowrap|wrap-reverse
,默认:nowrap
,控制项目是否换行以及换行方向。
wrap
:换行,项目在需要时换行,形成多行/多列布局。nowrap
:默认,不换行,所有项目强制在一行/列显示。wrap-reverse
:换行,项目在需要时换行,但方向相反。
语法特性:
换行与空间分配:
- 单行布局 (
nowrap
):- 所有项目共享同一主轴空间。
- 空间不足时项目收缩。
- 多行布局 (
wrap
/wrap-reverse
):- 每行形成独立的 flex 行。
- 每行空间独立分配。
align-content
控制行间对齐。
- 单行布局 (
与 flex-direction 的交互:
flex-direction flex-wrap: wrap flex-wrap: wrap-reverse row 从上到下换行 从下到上换行 row-reverse 从上到下换行 从下到上换行 column 从左到右换列 从右到左换列 column-reverse 从左到右换列 从右到左换列 行尺寸计算:每行的交叉轴尺寸由该行最高项目决定。行内项目默认拉伸填满行高。
最佳实践:
结合 gap 属性:
css/* 推荐:统一行列间距 */ .container { display: flex; flex-wrap: wrap; gap: 20px; } /* 不推荐:使用margin */ .item { margin: 10px; }
应用场景:
瀑布流布局:
css.masonry { display: flex; flex-direction: column; flex-wrap: wrap; height: 1000px; /* 固定高度 */ gap: 15px; } .masonry-item { width: 250px; /* 固定宽度 */ }
flex-flow
flex-flow: <flex-direction> | <flex-wrap>
,用于 同时设置 flex-direction
和 flex-wrap
的简写属性。
<flex-direction>:
row|row-reverse|column|column-reverse
,默认:row
,定义主轴方向,决定了 flex 容器内项目的排列方向和顺序。<flex-wrap>:
wrap|nowrap|wrap-reverse
,默认:nowrap
,控制项目是否换行以及换行方向。
语法特性:
简写优势:
css/* 使用 flex-flow 简写 */ .container { flex-flow: column wrap; } /* 等效于 */ .container { flex-direction: column; flex-wrap: wrap; }
顺序无关性:
css/* 两种写法等效 */ flex-flow: row wrap-reverse; flex-flow: wrap-reverse row;
align-content
align-content: flex-start|flex-end|center|space-between|space-around|space-evenly|stretch
,默认:stretch
,控制多行内容在交叉轴上的对齐方式,决定了容器内多行(或轨道)之间的空间分布方式。
flex-start
:项目向交叉轴起点对齐。flex-end
:项目向交叉轴终点对齐。center
:项目在交叉轴居中。space-between
:首尾项目贴边,中间项目等距。space-around
:每个项目两侧有相等空间。space-evenly
:所有空间均匀分配(包括边缘)。stretch
:默认,特有,拉伸项目填满容器。
语法特性:
适用条件:多行 Flex 容器 (
flex-wrap: wrap
)。控制对象:行与行之间的空间。
常见问题:
单行布局无效:
问题:单行布局(
flex-wrap: nowrap
)下不生效。css/* 错误:单行Flex容器 */ .flex-container { display: flex; /* flex-wrap: nowrap; (默认) */ align-content: center; /* 无效! */ }
解决:启用多行。
css/* 解决方案:启用多行 */ .flex-container { flex-wrap: wrap; }
示例:
多行居中:
html<div class="flex-container"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> </div>
css.flex-container { display: flex; flex-wrap: wrap; height: 400px; align-content: center; /* 多行整体居中 */ gap: 15px; } .item { flex: 0 0 150px; padding: 20px; background: #3498db; }
瀑布流布局:
css.masonry { display: flex; flex-wrap: wrap; flex-direction: column; height: 1000px; align-content: space-between; } .masonry-item { width: 200px; margin-bottom: 15px; }
项目属性
flex-grow
flex-grow: number
,默认:0
,控制项目如何分配容器剩余空间的关键属性,它决定了项目如何沿主轴方向扩展。
number
,非负数字(整数或小数):0
:项目不扩展,保持其初始大小。1+
:项目按比例分配剩余空间。小数:允许按比例扩展(如
0.5
)。
语法特性:
空间分配公式:
plain项目最终尺寸 = flex-basis + (剩余空间 × (flex-grow / ∑所有flex-grow))
计算示例:
- 初始总和:100px × 3 = 300px
- 剩余空间:600px - 300px = 300px
- 总增长因子:1 + 2 + 3 = 6
- 分配:
- Item1: 100px + (300px × 1/6) = 150px
- Item2: 100px + (300px × 2/6) = 200px
- Item3: 100px + (300px × 3/6) = 250px
css.container { width: 600px; } .item1 { flex-grow: 1; flex-basis: 100px; } .item2 { flex-grow: 2; flex-basis: 100px; } .item3 { flex-grow: 3; flex-basis: 100px; }
示例:
项目平均分配空间:
css.item { flex: 1; /* 所有项目平均分配空间 */ min-width: 0; /* 修复内容溢出问题 */ }
固定宽度与自适应组合:
css.fixed-width { flex: 0 0 200px; /* 不扩展,固定200px */ } .flexible { flex-grow: 1; /* 填充剩余空间 */ }
最小宽度约束:
css.card { flex-grow: 1; min-width: 250px; /* 防止过度缩小 */ }
flex-shrink
flex-shrink: number
,默认:1
,控制项目在空间不足时如何收缩的关键属性。
number
,非负数字(整数或小数):0
:项目不收缩,保持其初始大小。1+
:项目按比例收缩以适应容器。- 小数:允许按比例收缩(如
0.5
)。
语法特性:
空间收缩公式:
plain收缩比例 = (项目flex-shrink × 项目flex-basis) / ∑(所有项目的flex-shrink × flex-basis) 项目最终尺寸 = flex-basis - (超出空间 × 收缩比例)
示例计算:
- 初始总和:200px × 3 = 600px
- 超出空间:600px - 400px = 200px
- 总收缩因子:
- Item1: 1 × 200 = 200
- Item2: 2 × 200 = 400
- Item3: 3 × 200 = 600
- 总和:200 + 400 + 600 = 1200
- 收缩分配:
- Item1: 200px - (200px × 200/1200) = 200 - 33.33 = 166.67px
- Item2: 200px - (200px × 400/1200) = 200 - 66.67 = 133.33px
- Item3: 200px - (200px × 600/1200) = 200 - 100 = 100px
css.container { width: 400px; } .item1 { flex-shrink: 1; flex-basis: 200px; } .item2 { flex-shrink: 2; flex-basis: 200px; } .item3 { flex-shrink: 3; flex-basis: 200px; }
示例:
防止内容截断:
css.navigation-item { flex-shrink: 0; /* 禁止收缩,保持完整文本 */ padding: 10px 15px; white-space: nowrap; }
设置收缩上下限:
css.flex-item { flex-shrink: 1; min-width: 100px; /* 设置收缩下限 */ max-width: 300px; /* 设置收缩上限 */ }
误解收缩比例:
css/* 错误:认为收缩比例直接对比 */ .itemA { flex-shrink: 2; } .itemB { flex-shrink: 1; } /* 实际:收缩比例还取决于flex-basis */
flex-basis
flex-basis: auto|<width>|content
,默认:auto
,定义项目在主轴方向上的初始尺寸。
auto
:默认,自动尺寸,使用项目的width
/height
值,若未设置则根据内容计算。<width>
:Length
,显式尺寸设置。content
:基于内容尺寸,根据项目内容自动计算尺寸(忽略显式尺寸设置)。
语法特性:
与 width/height 的关系:
- 当
flex-basis: auto
时,使用width
/height
。 - 当
flex-basis
有值时,覆盖width
/height
。 - 在
flex-direction: column
中控制高度。
- 当
与 flex-grow/flex-shrink 的协作:
plain剩余空间 = 容器尺寸 - ∑(flex-basis) 项目最终尺寸 = flex-basis + (剩余空间 × flex-grow比例)
与 min-width/max-width 的交互:
css.item { flex-basis: 300px; min-width: 250px; /* 最小约束 */ max-width: 400px; /* 最大约束 */ }
示例:
基础尺寸设置:
css.item-fixed { flex-basis: 250px; /* 固定宽度 */ } .item-percent { flex-basis: 30%; /* 容器宽度的30% */ } .item-auto { flex-basis: auto; /* 根据内容或width决定 */ }
内容自适应:
html<div class="flex-container"> <div class="item">短文本</div> <div class="item content-basis">这是一段较长的文本内容</div> </div>
css.content-basis { flex-basis: content; /* 根据内容宽度 */ }
等分空间布局:
css.equal-columns { flex-basis: 0; /* 初始尺寸为0 */ flex-grow: 1; /* 所有空间平均分配 */ }
flex
flex: none|auto|<flex-grow>|<flex-shrink>|<flex-basis>
,用于 同时设置 flex-grow
、flex-shrink
和 flex-basis
的简写属性。
- none :
等价:0 0 auto
,项目不可伸缩,保持初始尺寸。 - auto:
等价:1 1 auto
,项目可自由伸缩,尺寸基于内容或宽度。 - <flex-grow>:
number
,默认:0
,控制项目如何分配容器剩余空间的关键属性,它决定了项目如何沿主轴方向扩展。 - <flex-shrink>:
number
,默认:1
,控制项目在空间不足时如何收缩的关键属性。 - <flex-basis>:
auto|<width>|content
,默认:auto
,定义项目在主轴方向上的初始尺寸。
语法特性:
常用配置解析:
配置 效果 适用场景 flex: 1
1 1 0%
等分空间 flex: auto
1 1 auto
内容自适应伸缩 flex: 0 auto
0 1 auto
不扩展但可收缩 flex: none
0 0 auto
固定尺寸不伸缩 flex: 2 1 200px
初始200px,可扩展可收缩 混合布局
示例:
基础布局配置:
html<div class="container"> <div class="item fixed">固定侧边栏</div> <div class="item fluid">主内容区</div> </div>
css.container { display: flex; height: 100vh; } .fixed { flex: 0 0 250px; /* 固定宽度 */ background: #f0f0f0; } .fluid { flex: 1; /* 占据剩余空间 */ background: #fff; }
简写:
css/* 推荐 - 简洁高效 */ .item { flex: 1 0 auto; } /* 等价写法: */ .item { flex-grow: 1; flex-shrink: 0; flex-basis: auto; }
order
order: number
,默认:0
,控制弹性项目或网格项目在容器内的显示顺序。
number
,默认:0
,整数值(正负整数和零):- 值越小:项目越靠前(在布局流中更早出现)。
- 值越大:项目越靠后(在布局流中更晚出现)。
- 相同值:项目按 HTML 源码顺序排列。
- 特殊值:
0
:项目保持 HTML 中的原始位置。负数
:比默认值更靠前显示。正数
:比默认值更靠后显示。
语法特性:
- 计算顺序:
- 所有项目按
order
值分组 - 每组内按 HTML 顺序排列
- 组间按
order
值升序排列
- 所有项目按
示例:
基础顺序调整:2 → 1 → 3
html<div class="container"> <div class="item1">1 (默认)</div> <div class="item2">2 (前移)</div> <div class="item3">3 (后移)</div> </div>
css.container { display: flex; } .item1 { order: 0; } /* 默认 */ .item2 { order: -1; } /* 向前移动 */ .item3 { order: 1; } /* 向后移动 */
align-self
align-self: flex-start|flex-end|center|baseline|stretch|auto
,控制单个项目在交叉轴上的对齐方式,允许覆盖容器上设置的 align-items
值。
flex-start
:项目向交叉轴起点对齐。flex-end
:项目向交叉轴终点对齐。center
:项目在交叉轴居中。baseline
:项目按基线对齐。stretch
:默认,项目拉伸填满容器高度。auto
:继承父容器的align-items
值。
语法特性:
与容器属性的关系:
align-self
优先级高于align-items
。交叉轴方向:
align-self
的行为取决于交叉轴方向:flex-direction: row
:控制垂直对齐。flex-direction: column
:控制水平对齐。
尺寸约束:
stretch
值受min-height/max-height
或min-width/max-width
限制。- 固定尺寸项目上
stretch
无效。
示例:
特殊项目居中:
html<div class="flex-container"> <div>项目1</div> <div>项目2</div> <div class="highlighted">重点内容</div> <div>项目4</div> </div>
css.flex-container { display: flex; height: 300px; align-items: flex-start; /* 默认顶部对齐 */ border: 1px solid #ccc; } .highlighted { align-self: center; /* 仅此项目居中 */ background: gold; padding: 20px; }
常见问题:
拉伸失效问题
css.stretch-item { align-self: stretch; height: auto; /* 必须移除固定高度 */ min-height: 0; /* 允许收缩 */ }